#include "MMP_lib.h"
#include "kk_memAdm.h"
#include "mxmem.h"
#include  "config_fw.h"

#define TOTAL_BARCODE_LIB_MEMORY 640*480*3

#define QR_MAXI(_a,_b)      ((_a)-((_a)-(_b)&-((_b)>(_a))))
#define QR_MINI(_a,_b)      ((_a)+((_b)-(_a)&-((_b)<(_a))))
#include "math.h"

volatile MMP_UBYTE* KK_MemBank;
//int KK_memIndex;
extern MMP_ULONG glPCCAM_VIDEO_BUF_MAX_SIZE;
extern MMP_ULONG glPCCAM_VIDEO_BUF_ADDR;

//char GodBuffer[TOTAL_BARCODE_LIB_MEMORY];

void KK_Reset_MemBank(void)
{
	//KK_memIndex = 0;
	mxinit((void *)KK_MemBank, TOTAL_BARCODE_LIB_MEMORY);
}

void KK_Initial_MemBank(void)
{
#if (DYNAMIC_CONFIG_CACHEBUF == 1)
	extern void MMPF_MMU_ConfigWorkingBuffer(unsigned int startAddr, unsigned int endAddr, char cacheable);
	glPCCAM_VIDEO_BUF_MAX_SIZE = TOTAL_BARCODE_LIB_MEMORY;

	KK_MemBank = (MMP_UBYTE*)MMPF_SYS_AllocFB("YUY2",TOTAL_BARCODE_LIB_MEMORY,4096);
	PCAM_USB_ResetSlotBuf(1, 1,(MMP_ULONG)KK_MemBank, TOTAL_BARCODE_LIB_MEMORY);

	//glPCCAM_VIDEO_BUF_ADDR = KK_MemBank;
	MMPF_MMU_ConfigWorkingBuffer((MMP_ULONG)KK_MemBank, (MMP_ULONG)KK_MemBank+glPCCAM_VIDEO_BUF_MAX_SIZE, MMP_TRUE);

#else
	//KK_MemBank = (MMP_UBYTE*)GodBuffer;
	KK_MemBank = (MMP_UBYTE*)malloc(TOTAL_BARCODE_LIB_MEMORY);
	
	//KK_MemBank =  (MMP_UBYTE*)MMPF_SYS_AllocFB("YUY2",TOTAL_BARCODE_LIB_MEMORY,2);
	//PCAM_USB_ResetSlotBuf(1, 1,(MMP_ULONG)KK_MemBank, TOTAL_BARCODE_LIB_MEMORY);
	
#endif

	KK_Reset_MemBank();
	//mxinit((void *)KK_MemBank, TOTAL_BARCODE_LIB_MEMORY);
}

/*
void* KK_AllocBuffer(unsigned long i_size)
{
	void* p = (char*)KK_MemBank+KK_memIndex;

	KK_memIndex += i_size;
	
	return p;
}
*/

#if 0//def ZDW_USE_CORE_BINARIZER
void kk_BinarizeImg(MMP_UBYTE* ImgData, int iWidth, int iHeight)
{
	MMP_BYTE * lv_pbtMask = NULL;
	int            lv_iLogwindW;
	int            lv_iLogWindH;
	int            lv_iWindW;
	int            lv_iWindH;
	int            lv_iY0offs;
	int            lv_iY1offs;
	unsigned       lv_uiG;
	int            lv_iX;
	int            lv_iY;
	unsigned lv_uiM;
	int      lv_iX0;
	int      lv_iX1;
	unsigned *lv_puiCol_sums;
	
	//Allocate temp buffer
	lv_pbtMask = (MMP_BYTE*)KK_AllocBuffer(iWidth*iHeight);
	lv_puiCol_sums = (unsigned*)KK_AllocBuffer(iWidth*4);

	if(iWidth>0&&iHeight>0)
	{
		//lv_puiCol_sums = (unsigned*)ZDRandomApplyBuffInt(iWidth);
		
		for(lv_iLogwindW=4;lv_iLogwindW<8&&(1<<lv_iLogwindW)<((iWidth+7)>>3);lv_iLogwindW++);
		for(lv_iLogWindH=4;lv_iLogWindH<8&&(1<<lv_iLogWindH)<((iHeight+7)>>3);lv_iLogWindH++);
		lv_iWindW=1<<lv_iLogwindW;
		lv_iWindH=1<<lv_iLogWindH;

		for(lv_iX=0;lv_iX<iWidth;lv_iX++)
		{
			lv_uiG=ImgData[lv_iX];
			lv_puiCol_sums[lv_iX]=(lv_uiG<<(lv_iLogWindH-1))+lv_uiG;
		}

		for(lv_iY=1;lv_iY<(lv_iWindH>>1);lv_iY++)
		{
			lv_iY1offs=QR_MINI(lv_iY,iHeight-1)*iWidth;
			for(lv_iX=0;lv_iX<iWidth;lv_iX++)
			{
				lv_uiG=ImgData[lv_iY1offs+lv_iX];
				lv_puiCol_sums[lv_iX]+=lv_uiG;
			}
		}

		for(lv_iY=0;lv_iY<iHeight;lv_iY++)
		{
			/**
			 * Initialize the sum over the window.
			 **/
			lv_uiM=(lv_puiCol_sums[0]<<(lv_iLogwindW-1))+lv_puiCol_sums[0];
			for(lv_iX=1;lv_iX<(lv_iWindW>>1);lv_iX++)
			{
				lv_iX1=QR_MINI(lv_iX,iWidth-1);
				lv_uiM+=lv_puiCol_sums[lv_iX1];
			}
			for(lv_iX=0;lv_iX<iWidth;lv_iX++)
			{
				/**
				 * Perform the test against the threshold T = (m/n)-D,
				 * where n=windw*windh and D=3.
				 **/
				lv_uiG=ImgData[lv_iY*iWidth+lv_iX];
				lv_pbtMask[lv_iY*iWidth+lv_iX]=-(((lv_uiG+3)<<(lv_iLogwindW+lv_iLogWindH))<lv_uiM)&0xFF;
	
				/**
				 * Update the window sum.
				 **/
				if(lv_iX+1<iWidth)
				{
					lv_iX0=QR_MAXI(0,lv_iX-(lv_iWindW>>1));
					lv_iX1=QR_MINI(lv_iX+(lv_iWindW>>1),iWidth-1);
					lv_uiM+=lv_puiCol_sums[lv_iX1]-lv_puiCol_sums[lv_iX0];
				}
			}
			/**
			 * Update the column sums.
			 **/
			if(lv_iY+1<iHeight)
			{
				lv_iY0offs=QR_MAXI(0,lv_iY-(lv_iWindH>>1))*iWidth;
				lv_iY1offs=QR_MINI(lv_iY+(lv_iWindH>>1),iHeight-1)*iWidth;
				for(lv_iX=0;lv_iX<iWidth;lv_iX++)
				{
					lv_puiCol_sums[lv_iX]-=ImgData[lv_iY0offs+lv_iX];
					lv_puiCol_sums[lv_iX]+=ImgData[lv_iY1offs+lv_iX];
				}
			}
		}

	}

	//BinaryImg
	{
		int lv_iSize ;
		MMP_BYTE * lv_pbtSrcCur;
		MMP_BYTE * lv_pbtSrcEnd;
		MMP_BYTE * lv_pbtDstCur;

		lv_iSize = iWidth*iHeight;
		lv_pbtSrcCur = (MMP_BYTE *)ImgData;
		lv_pbtSrcEnd = (MMP_BYTE *)(ImgData + lv_iSize);
		lv_pbtDstCur = lv_pbtMask;

		//AIT_debugMsg("ZDW BinaryImg", lv_iSize, 0);
		while( lv_pbtSrcCur<lv_pbtSrcEnd)
		{
			//unsigned char& lv_btRef = (unsigned char&)*lv_pbtSrcCur;
			if ( *lv_pbtSrcCur>*lv_pbtDstCur)
			{
				*lv_pbtSrcCur = 255;
			}
			else
			{
				*lv_pbtSrcCur = 0;
			}
			++lv_pbtSrcCur;
			++lv_pbtDstCur;
		}
	}






}
#endif

#if 0
MMP_UBYTE KK_GammaTable[256];
void KK_InitGammaTable(void)
{
	int i;
	double fnum;
	for(i=0;i<256;i++)
	{
		fnum = pow(((double)i/256),1.6);
		KK_GammaTable[i] = 256*fnum;
	}
}

#endif